/*
 * This class is constructed with inspiration from the following sources:
 *  - http://android10.org/index.php/articleslocationmaps/253-how-to-use-google-maps-in-android
 *  - http://stackoverflow.com/questions/5241487/android-mapview-setting-zoom-automatically-until-all-itemizedoverlays-are-visi
 *  - http://stackoverflow.com/questions/2023669/j2me-android-blackberry-driving-directions-route-between-two-locations
 */

package emt.friendtracking.maps;

import java.io.InputStream;
import java.util.List;

import com.google.android.maps.*;

import emt.friendtracking.BaseActivity;
import emt.friendtracking.Data;
import emt.friendtracking.MyApplication;
import emt.friendtracking.R;
import emt.friendtracking.maps.org.ci.geo.route.*;

import android.content.Intent;
import android.graphics.*;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
 
public class TrackingActivity extends BaseActivity
{
	private static final String TAG = TrackingActivity.class.getSimpleName();
	private MapController controller;
	private MapView mapView;
	List<Overlay> overlays;
    private Road mRoad;
    
    protected static Data.Information information;
    
    public static Data.Information getInformation()
    {
    	return information;
    }
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.trackfriend);
        mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);
        
        overlays = mapView.getOverlays();

    	Log.d(TAG, "onCreated."); //TODO "onCreated."
        controller = mapView.getController();
        long toGet = BaseActivity.getIdOfNewRow();
        Log.d(TAG, "toGet: " + toGet);
        if(toGet!=-1)
        {
        	Log.d(TAG, "Going to display route.");
        	BaseActivity.setIdOfNewRow(-1);

        	Data data = new Data();

        	information = data.getItemById(toGet);
        	data.close();
        	
        	Log.d(TAG, "cursor string: " + information.getUserName());

        	this.displayLocation(information.getLatitudeMe(), information.getLongitudeMe(), information.getLatitudeOther(), information.getLongitudeOther(), information.getUserName());
        	
        	new Thread()
    		{
    			public void run()
    			{
    				try
    				{
    					sleep(60000);
    		        	startService(new Intent(MyApplication.getAppContext(), TimeToArrival.class));
    				}
    				catch(InterruptedException e)
    				{ }
    			}
    		}.start();
        }
    }
    
    protected boolean isRouteDisplayed()
    {
        return false;
    }
    
    /**
     * 
     * @param originLatitude
     * @param originLongitude
     * @param destLatitude
     * @param destLongitude
     * @param personToFind Name of the person find. The name will be written on the map
     */
    public void displayLocation(double originLatitude, double originLongitude, double destLatitude, double destLongitude, String personToFind)
    {	
    	GeoPoint origin = new GeoPoint((int)(originLatitude * 1E6), (int)(originLongitude * 1E6));
    	GeoPoint destination = new GeoPoint((int)(destLatitude * 1E6), (int)(destLongitude * 1E6));
    	
    	zoomToSpan(origin.getLatitudeE6(), origin.getLongitudeE6(), destination.getLatitudeE6(), destination.getLongitudeE6());
    	
    	overlays.clear();
    	overlays.add(new EndPointOverlay(origin));
    	overlays.add(new EndPointOverlay(destination, personToFind));    	
    	drawRoute(originLatitude, originLongitude, destLatitude, destLongitude);
    	
    	mapView.invalidate();
    }

	private void zoomToSpan(int originLat, int originLon, int destLat, int destLon)
	{        
    	int minLat = Integer.MAX_VALUE;
    	int maxLat = Integer.MIN_VALUE;
    	int minLon = Integer.MAX_VALUE;
    	int maxLon = Integer.MIN_VALUE;
    	
        maxLat = Math.max(originLat, maxLat);
        maxLat = Math.max(destLat, maxLat);
        
        minLat = Math.min(originLat, minLat);
        minLat = Math.min(destLat, minLat);
        
        maxLon = Math.max(originLon, maxLon);
        maxLon = Math.max(destLon, maxLon);
        
        minLon = Math.min(originLon, minLon);
        minLon = Math.min(destLon, minLon);
    	
    	double paddingFactor = 1.3;
    	controller.zoomToSpan((int)(Math.abs(maxLat - minLat) * paddingFactor), (int)(Math.abs(maxLon - minLon) * paddingFactor));
    	controller.animateTo(new GeoPoint((maxLat+minLat)/2, (maxLon+minLon)/2));
	}
	
    class EndPointOverlay extends com.google.android.maps.Overlay
    {
    	private GeoPoint point;
    	private String personToFind;
    	
    	public EndPointOverlay(GeoPoint p)
    	{
    		point = p;
    	}
    	
    	public EndPointOverlay(GeoPoint p, String personToFind)
    	{
    		point = p;
    		this.personToFind = personToFind;
    	}
    	
        @Override
        public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) 
        {
            super.draw(canvas, mapView, false);                   
 
            android.graphics.Point screenPts = new android.graphics.Point();
            mapView.getProjection().toPixels(point, screenPts);
//            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pin);            
//            canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 46, null);
            
            if (personToFind != null)
            {
	            Paint paint = new Paint();
	            paint.setTextSize(20);
	            paint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
	
	            canvas.drawText(personToFind, screenPts.x, screenPts.y + 10, paint);
            }
            return true;
        }
    }    

	private double drawRouteOriginLatitude, drawRouteOriginLongitude, drawRouteDestLatitude, drawRouteDestLongitude;
	
	private void drawRoute(final double originLatitude, final double originLongitude, final double destLatitude, final double destLongitude)
	{
		this.drawRouteOriginLatitude = originLatitude; this.drawRouteOriginLongitude = originLongitude; this.drawRouteDestLatitude = destLatitude; this.drawRouteDestLongitude = destLongitude;
		new Thread()
		{
			@Override
			public void run()
			{
				String url = RoadProvider.getUrl(originLatitude, originLongitude, destLatitude, destLongitude);
				InputStream is = Helper.getConnection(url);
				mRoad = RoadProvider.getRoute(is);
				mHandler.sendEmptyMessage(0);
			}
		}.start();
	}
	
	Handler mHandler = new Handler()
	{
		public void handleMessage(android.os.Message msg)
		{
			MapRouteOverlay mapOverlay = new MapRouteOverlay(mRoad, mapView);
			mapView.getOverlays().add(mapOverlay);
			zoomToSpan((int)(drawRouteOriginLatitude * 1E6), (int)(drawRouteOriginLongitude * 1E6), (int)(drawRouteDestLatitude * 1E6), (int)(drawRouteDestLongitude * 1E6));
		};
	};
}